查看原文
其他

电子数显控件,隔壁产品都馋哭了

技术最TOP 2022-08-26

The following article is from 也路子 Author 彭也

阅读完本文约需6分钟。

废不说,有图

模拟电子手表的时钟数显,适合用在时钟、数字电子风格显示等场景。

可以注意到,本控件还原了电子手表上数字显示的残影效果,在显示某个具体数字时,仍然可以隐约看见数字“8”的形状。

将这个控件用在大屏全面屏手机上,作为一个工作时钟也是个不错的选择。


一、设计思路

模拟现实生活中的上古时代电子手表进行设计还原。为更加贴近现实中的电子手表,也提供了像素栅格的绘制

是不是更有那味儿了?


二、实现方式

2.1 UI拆解

2.1.1 形状分析

可以观察到,控件由同一个基础形状通过不同位置的摆放组合而成

2.1.2 数字分类

所有的数字都由数字“8”的形状组成,不同部位涂抹不同颜色而呈现不同数字



2.2 UI绘制

2.2.1 绘制基本形状

定义全局的mPath变量用于绘制基本形状,封装一个绘制基本形状的方法


/**     * 绘制骨架单元     *     * @param w 宽     * @param h 高     */    private void drawUnit(Canvas canvas, int w, int h) {        if (mPath == null) {            mPath = new Path();            // 间隔,相当于padding            int d = 5;            mPath.moveTo(d, h / 2);            mPath.lineTo(h / 2 + d, 0);            mPath.lineTo(w - h / 2 - d, 0);            mPath.lineTo(w - d, h / 2);            mPath.lineTo(w - h / 2 - d, h);            mPath.lineTo(h / 2 + d, h);            mPath.lineTo(d, h / 2);            mPath.close();        }
        canvas.drawPath(mPath, unitPaint);
        //todo:绘制网格    }


2.2.2 绘制数字“8”

为表现出数显残影效果,所有的数字由数字“8”的形状组成,涂抹不同位置的颜色显示不同的数字。绘制完基本形状后,对基本形状进行旋转、平移等操作即可组成数字“8”形状。


/** * 绘制数字 * * @param canvas * @param num    数字 */private void drawNum(Canvas canvas, int num) {    //绘制第1个    unitPaint.setColor(NumColors.getTargetNumColors(num).colors[0]);    canvas.translate(uintH / 2, 0);    drawUnit(canvas, uintW, uintH);
    //绘制第2个    unitPaint.setColor(NumColors.getTargetNumColors(num).colors[1]);    canvas.translate(uintW + uintH / 2, 0);    canvas.rotate(90);    canvas.translate(uintH / 2, 0);    drawUnit(canvas, uintW, uintH);
    //绘制第3个    unitPaint.setColor(NumColors.getTargetNumColors(num).colors[2]);    canvas.translate(uintW, 0);    drawUnit(canvas, uintW, uintH);
    //绘制第4个    unitPaint.setColor(NumColors.getTargetNumColors(num).colors[3]);    canvas.translate(uintW + uintH / 2, 0);    canvas.rotate(90);    canvas.translate(uintH / 2, 0);    drawUnit(canvas, uintW, uintH);
    //绘制第5个    unitPaint.setColor(NumColors.getTargetNumColors(num).colors[4]);    canvas.translate(uintW + uintH / 2, 0);    canvas.rotate(90);    canvas.translate(uintH / 2, 0);    drawUnit(canvas, uintW, uintH);
    //绘制第6个    unitPaint.setColor(NumColors.getTargetNumColors(num).colors[5]);    canvas.translate(uintW, 0);    drawUnit(canvas, uintW, uintH);
    //绘制第7个    unitPaint.setColor(NumColors.getTargetNumColors(num).colors[6]);    canvas.rotate(90);    canvas.translate(uintH / 2, -uintH / 2);    drawUnit(canvas, uintW, uintH);}


2.2.3 数字枚举

有了数字“8”形状的骨架,定义不同的数字枚举即可实现不同数字的绘制。同时定义好残影颜色和数显颜色,方便日后定制扩展。


/*** 默认骨架颜色*/@ColorIntpublic static int uintBgColor = Color.parseColor("#e8e8e8");
/*** 选中的骨架颜色*/@ColorIntpublic static int uintSelectedColor = Color.DKGRAY;

/** * 每个数字对应的颜色数组枚举 */enum NumColors {
    NUM_0(new int[]{uintSelectedColor, uintSelectedColor, uintSelectedColor, uintSelectedColor, uintSelectedColor, uintSelectedColor, uintBgColor}),    NUM_1(new int[]{uintBgColor, uintSelectedColor, uintSelectedColor, uintBgColor, uintBgColor, uintBgColor, uintBgColor}),    NUM_2(new int[]{uintSelectedColor, uintSelectedColor, uintBgColor, uintSelectedColor, uintSelectedColor, uintBgColor, uintSelectedColor}),    NUM_3(new int[]{uintSelectedColor, uintSelectedColor, uintSelectedColor, uintSelectedColor, uintBgColor, uintBgColor, uintSelectedColor}),    NUM_4(new int[]{uintBgColor, uintSelectedColor, uintSelectedColor, uintBgColor, uintBgColor, uintSelectedColor, uintSelectedColor}),    NUM_5(new int[]{uintSelectedColor, uintBgColor, uintSelectedColor, uintSelectedColor, uintBgColor, uintSelectedColor, uintSelectedColor}),    NUM_6(new int[]{uintSelectedColor, uintBgColor, uintSelectedColor, uintSelectedColor, uintSelectedColor, uintSelectedColor, uintSelectedColor}),    NUM_7(new int[]{uintSelectedColor, uintSelectedColor, uintSelectedColor, uintBgColor, uintBgColor, uintBgColor, uintBgColor}),    NUM_8(new int[]{uintSelectedColor, uintSelectedColor, uintSelectedColor, uintSelectedColor, uintSelectedColor, uintSelectedColor, uintSelectedColor}),    NUM_9(new int[]{uintSelectedColor, uintSelectedColor, uintSelectedColor, uintSelectedColor, uintBgColor, uintSelectedColor, uintSelectedColor});
    /**     * 数字对应的颜色数组     */    int colors[];
    NumColors(int[] colors) {        this.colors = colors;    }
    public static NumColors getTargetNumColors(int num) {        switch (num) {            case 0:                return NUM_0;            case 1:                return NUM_1;            case 2:                return NUM_2;            case 3:                return NUM_3;            case 4:                return NUM_4;            case 5:                return NUM_5;            case 6:                return NUM_6;            case 7:                return NUM_7;            case 8:                return NUM_8;            case 9:                return NUM_9;            default:                return NUM_0;        }    }}


2.3 栅格绘制

栅格绘制使用到了Paint绘制时的叠加方式,思路是这样的,先绘制基本形状,再在裁剪成基本形状的画布上绘制栅格,最后排除重叠的栅格绘制内容

2.3.1 绘制的叠加方式简介

通过Paint.setXfermode进行设置,参数通过PorterDuff.Mode枚举进行选取。

2.3.2 代码绘制

确定好叠加模式后,裁剪出基本形状的画布,继而绘制栅格。需要注意的是调用restore方法,方便其它基本形状位置的摆放绘制。


//绘制网格if (isDrawGrid) {    canvas.save();    canvas.clipPath(mPath);    canvas.drawPath(mPath, unitPaint);    unitPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SCREEN));    canvas.drawPath(getGridPath(w, h), unitPaint);    unitPaint.setXfermode(null);    canvas.restore();} else {    canvas.drawPath(mPath, unitPaint);}


最后的效果

三、后记

所有的UI交互控件都应该是基于现实的抽象与改进,集可用性、美观性、便捷性于一体。

从控件设计和实现一窥相关行业方向。控件设计可能会经历以下三个阶段:

第一阶段:对现实生活中的工具进行抽象,演化成不同的UI提供给用户;

第二阶段:在抽象的基础上进行派生,新增更适合手机屏幕的平面交互方式;

第三阶段:回归现实,所有的控件成为现实生活中的一部分,它可能在你家的沙发上,也可能在你家的浴室里,完全融入现实生活而不显突兀。

控件地址在gitee

点“阅读原文”获取


微信更新了8.0版本,有很多好玩的功能,没有更新的可以去更新看看,除此之外,微信的好友上限也扩展到1000人,西哥好友位开放,还没有加西哥好友的,可以扫下面二维码加个好友,有职场、技术相关问题,随时咨询



---END---

推荐阅读:
网易北京员工核酸阳性,全员居家隔离办公
踩坑之路:finish方法执行后居然还有这种操作?
刚刚!微信8.0版本重大更新!全新Q弹的动态表情,屏幕炸弹、烟花动效!
把LayoutManager撸出花儿来,自定义无限循环的LayoutManager!
为什么祖传代码会被称为屎山
把HashMap剖析的只剩渣了!
Java之戳中痛点之 synchronized 深度解析
StackOverflow 上拷贝的代码片段,崩了!
Android Studio启用新代号,新版本Arctic Fox(白狐)重点新特性一览!


更文不易,点个“在看”支持一下👇

您可能也对以下帖子感兴趣

文章有问题?点此查看未经处理的缓存